#!/usr/bin/python3.6
# coding：utf-8
import subprocess

'说明：备份的是用户的整个目录，恢复时，直接覆盖用户目录即可'
# 常量参数：anki用户名, 备份数量上限, 用户数据所在目录, 备份目录,
set_count = 5
target = 'test'
# dir_target = '/opt/anki/collections/'
# dir_backup = '/mnt/f/__Desktop/z__Backup/anki/'
dir_target = '/mnt/c/Users/56473/AppData/Roaming/Anki2/'
dir_backup = '/mnt/f/__Desktop/z__Backup/anki/'
# 排除的打包目录 or 文件
exclude = 'backups'
exclude = target+'/'+exclude
# 变量参数
backup_list, backup_1, backup_9, backup_count = [], '', '', 0
stat_target, stat_backup_9 = 0, 0
# 命令函数：获取当前文件, 获取更新时间，压缩, 删除
ls = 'ls {}'
stat = 'stat -c %Y {}'
tar = 'tar -czf {} --exclude={} {}'
rm = 'rm {}'
ls_l = 'ls -l {}'
date_c = 'date +%Y%m%d_%H%M%S'
cd = 'cd {}'
touch = 'touch {}'


class Cmd:
    @classmethod
    def cmd(cls, *args, _print=False):
        s01 = '&&'
        x = s01.join(args)  # 拼接命令
        read = subprocess.getoutput(x)  # 执行命令
        # 检测命令结果
        for i in x.split(s01):
            print(f'执行命令：{i}')
            i_ahead = i.split(' ')[0]
            if f'{i_ahead}:' in read:
                raise SystemExit(f'错误：{read}')
        # 输出
        if _print:
            print(read)
        readlines = read.split('\n')
        return readlines

    def __init__(self):
        # self.cmd(touch.format(dir_target+target))  # 测试，启用时将更新备份文件
        self.__get_info()  # 先获取必要的信息
        self.main()  # 然后执行各种命令
        self.cmd(ls_l.format(dir_backup), _print=True)  # 查看结果

    def __get_info(self):
        global backup_list, backup_1, backup_9, backup_count
        global stat_target, stat_backup_9
        c1 = ls.format(dir_backup)
        backup_list = self.cmd(c1, _print=False)
        backup_1, backup_9 = backup_list[0], backup_list[-1]
        backup_count = len(backup_list)
        print(f'当前文件数量：{backup_count}')
        print(f'第一个，最后一个文件分别为：{backup_1}; {backup_9}')
        # 获取文件的 更新时间
        stat_target = int(self.cmd(stat.format(dir_target + target))[0])
        stat_backup_9 = int(self.cmd(stat.format(dir_backup + backup_9))[0])

    def main(self):
        stat_list = stat_target, stat_backup_9
        # 判断：压缩
        if stat_list[0] > stat_list[1]:
            print('{} > {}, 文件有更新, 执行备份操作'.format(*stat_list))
            self.exe_tar()
            self.exe_rm()  # 判断：删除
        else:
            print('{} > {}, 文件没有更新，不执行压缩'.format(*stat_list))

    def exe_rm(self):
        """
        当备份文件大于上限时，删除前两个。
        把列表翻转，排在后面且超出索引的，就是要删除的
        """
        a01 = backup_list
        rm_list = []
        count = backup_count
        if count > set_count:
            print(f'压缩包数量：{count} > 设置数量：{set_count}；删除文件')
            a01.reverse()
            for i, item in enumerate(a01):
                if i >= set_count:
                    rm_list.append(item)
            rm_list_str = ' '.join(rm_list)
            c0 = cd.format(dir_backup)
            c1 = rm.format(rm_list_str)  # 执行删除
            self.cmd(c0,c1)
        else:
            print(f'压缩包数量：{count} <= 设置数量：{set_count}；不删除文件')

    def exe_tar(self):
        date01 = self.cmd(date_c)[0]
        tar_name = f'{target}Backup_{date01}.tgz'
        c1 = cd.format(dir_target)  # 进入目标路径
        c2 = tar.format(dir_backup + tar_name, exclude, target)  # 执行压缩
        self.cmd(c1, c2)
        global backup_count, backup_list
        backup_count += 1
        backup_list.append(tar_name)


Cmd()
